package org.whb.user.service.impl;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.whb.basic.constant.LoginConstant;
import org.whb.basic.exception.BusinessException;
import org.whb.basic.service.impl.BaseServiceImpl;
import org.whb.basic.util.MD5Utils;
import org.whb.basic.util.StrUtils;
import org.whb.user.domain.Logininfo;
import org.whb.user.domain.User;
import org.whb.user.dto.UserDto;
import org.whb.user.mapper.LogininfoMapper;
import org.whb.user.mapper.UserMapper;
import org.whb.user.service.IUserService;

@Service
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService  {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 主站用户注册
     * @param dto 前端返回的参数
     */
    @Override
    @Transactional
    public void phoneRegister(UserDto dto) {
        //一、判断前端返回的数据是否为空
        if(StringUtils.isEmpty(dto.getPhoneNum())
                || StringUtils.isEmpty(dto.getVerifyCode())
                || StringUtils.isEmpty(dto.getPassword())
                || StringUtils.isEmpty(dto.getConfirmPassword())){
            throw new BusinessException("注册信息不能为空！");
        }
        //判断两次密码和确认密码是否一致
        if(!dto.getPassword().equals(dto.getConfirmPassword())){
           throw new BusinessException("请确保两次输入密码一致！");
        }
        //二、判断该用户是否注册过
        User userExist = userMapper.loadByPhone(dto.getPhoneNum());
        if(userExist!=null){ //该用户已经存在
            throw new BusinessException("该用户已存在，请直接登录");
        }
        //三、判断验证码是否正确
        //通过key去获取redis中存的验证码
        String verifyKey = LoginConstant.PHONE_REGISTER+dto.getPhoneNum();
        Object redisVerifyCodeAndTime = redisTemplate.opsForValue().get(verifyKey);
        if(redisVerifyCodeAndTime==null){ //验证码过期
            throw new BusinessException("验证码已过期，请重新获取验证码！！！");
        }
        String inputVerifyCode = dto.getVerifyCode();
        String redisVerifyCode = redisVerifyCodeAndTime.toString().split(":")[0];
        if(!inputVerifyCode.equals(redisVerifyCode)){ //验证码错误
            throw new BusinessException("验证码错误！！！");
        }
        //将注册信息存入logininfo
        User user = dto2User(dto);
        Logininfo logininfo = User2logininfo(user);
        logininfoMapper.save(logininfo); //保存logininfo中的信息，同时返回id
        user.setLogininfo_id(logininfo.getId());
        userMapper.save(user);
    }

    /**
     * 将user对象转为logininfo对象
     * @param user
     * @return
     */
    private Logininfo User2logininfo(User user) {
        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(user, logininfo);
        logininfo.setType(1);
        return logininfo;
    }

    /**
     * 将dto转为user对象
     * @param dto
     * @return
     */
    private User dto2User(UserDto dto) {
        User user = new User();
        user.setUsername(dto.getPhoneNum());
        user.setPhone(dto.getPhoneNum());
        //生成盐值
        String salt = StrUtils.getComplexRandomString(32);
        //加密加盐
        String password = MD5Utils.encrypByMd5(dto.getPassword() + salt);

        user.setSalt(salt);
        user.setPassword(password);
        return user;
    }


}
